<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>艾宾浩斯复习页码生成工具</title>
  <style>
    :root{
      --bg:#0b1220;--card:#111a2b;--accent:#7c9cff;--muted:#a7b4d8;--ok:#29c68d;--warn:#ffae42;--err:#ff6b6b;
    }
    *{box-sizing:border-box}
    body{margin:0;font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Inter,Helvetica,Arial,"Apple Color Emoji","Segoe UI Emoji";background:linear-gradient(180deg,#0b1220,#0d1526 35%,#0b1220);color:#e8eeff;min-height:100vh;display:flex;align-items:center;justify-content:center}
    .wrap{width:min(900px,92vw);padding:28px}
    .card{background:var(--card);border:1px solid rgba(124,156,255,.18);box-shadow:0 10px 40px rgba(124,156,255,.08),inset 0 0 0 1px rgba(255,255,255,.03);border-radius:22px;padding:26px}
    h1{font-size:28px;margin:0 0 12px 0;letter-spacing:.4px}
    p.sub{margin:.25rem 0 1rem 0;color:var(--muted)}
    .row{display:flex;gap:12px;flex-wrap:wrap;align-items:center}
    input[type="text"]{flex:1;min-width:240px;background:#0a1120;border:1px solid rgba(255,255,255,.12);border-radius:14px;padding:14px 16px;color:#e8eeff;font-size:16px;outline:none;transition:.2s}
    input[type="text"]:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(124,156,255,.25)}
    button{background:var(--accent);color:#0a0f1d;border:0;border-radius:14px;padding:14px 18px;font-weight:700;font-size:15px;cursor:pointer;transition:transform .06s ease, box-shadow .2s ease}
    button:active{transform:translateY(1px)}
    .hint{font-size:13px;color:var(--muted);margin-top:8px}
    .error{color:var(--err);margin-top:10px;display:none}
    .results{margin-top:22px;display:none}
    .list{display:grid;gap:10px;margin-top:10px}
    .item{background:#0a1120;border:1px solid rgba(255,255,255,.08);border-radius:14px;padding:12px 14px;display:flex;justify-content:space-between;align-items:center}
    .badge{font-size:12px;color:#091126;background:linear-gradient(90deg,#b7c8ff,#86a2ff);border-radius:999px;padding:6px 10px;font-weight:700}
    .range{font-variant-numeric:tabular-nums;font-weight:600}
    .footer{margin-top:16px;padding:12px 14px;border-radius:14px;background:rgba(41,198,141,.1);border:1px solid rgba(41,198,141,.35);color:#d6ffef;display:flex;gap:8px;align-items:center}
    .footer b{color:#8ff0c3}
    .tips{margin-top:10px;color:var(--muted);font-size:13px}
    .small{font-size:12px;color:var(--muted)}
    .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
  </style>
</head>
<body>
  <div class="wrap">
    <div class="card">
      <h1>📘 艾宾浩斯复习页码生成工具</h1>
      <p class="sub">规则：默认你<strong>每天学习 2 页</strong>且连续推进；今天输入的是你<span class="small">（Day N）</span>学习的页码范围，系统按 1 / 2 / 4 / 7 / 15 / 30 天计划自动计算今日复习内容，并做<strong>合并去重</strong>。</p>

      <div class="row" role="group" aria-label="工具输入区">
        <label class="sr-only" for="today">今日学习页码</label>
        <input id="today" type="text" placeholder="例如：P29-P30" autocomplete="off" />
        <button id="go">生成复习计划</button>
      </div>
      <div class="hint">输入格式：<code>Px-Py</code>（如 <code>P29-P30</code>，大小写均可）。默认昨天为前两页（例如 <code>P27-P28</code>）。</div>
      <div id="err" class="error">❌ 输入不合法。请使用格式 <b>Px-Py</b>，且两页应为连续的 2 页（如 P12-P13）。</div>

      <div id="res" class="results">
        <h2 style="margin:10px 0 8px 0;font-size:20px">今日复习内容：</h2>
        <div id="list" class="list"></div>
        <div id="summary" class="footer">📎 合并去重后共需复习 <b id="total">0</b> 页：<span id="merged"></span></div>
        <div class="tips">提示：若遇到 <code>P1</code> 之前的页码，会自动从 <code>P1</code> 起向后补足应复习的连续页数。</div>
      </div>
    </div>
  </div>

  <script>
    const input = document.getElementById('today');
    const btn = document.getElementById('go');
    const err = document.getElementById('err');
    const res = document.getElementById('res');
    const list = document.getElementById('list');
    const totalEl = document.getElementById('total');
    const mergedEl = document.getElementById('merged');

    const OFFSETS = [1,2,4,7,15,30];

    function parseRange(str){
      const m = /^\s*[Pp](\d+)\s*-\s*[Pp](\d+)\s*$/.exec(str||'');
      if(!m) return null;
      const a = parseInt(m[1],10), b = parseInt(m[2],10);
      if(!(Number.isFinite(a) && Number.isFinite(b))) return null;
      if(b !== a+1 || a<1 || b<1) return null; // 必须为连续 2 页
      return {start:a, end:b, daily:2};
    }

    function clampBlock(start, len){
      // 只考虑下界 P1；若 start < 1，则从 P1 起向后补足 len 页
      if(len < 1) return null;
      if(start >= 1) return {s:start, e:start + len - 1};
      const e = 1 + (len - 1); // 例如 len=4 -> P1-P4
      return {s:1, e:e};
    }

    function compute(today){
      const {start, daily} = today; // 今日首页，如 29
      const blocks = []; // {label, s, e}
      const shown = [];  // 已展示的区间，用于去重（跳过完全被包含的）

      for(const d of OFFSETS){
        const len = (d <= 2) ? daily : daily*2; // 1/2 天复习 2 页；≥4 天复习 4 页
        const idealStart = start - daily*d;    // 该复习块的起始页（可能 < 1）
        const block = clampBlock(idealStart, len);
        if(!block) continue;

        // 跳过被先前块完全覆盖的重复范围
        let covered = false;
        for(const r of shown){
          if(block.s >= r.s && block.e <= r.e){ covered = true; break; }
        }
        if(covered) continue;

        shown.push(block);
        blocks.push({ label: d+"天前", s: block.s, e: block.e, offset:d });
      }

      // 生成合并后的区间（对显示顺序无影响）
      const merged = mergeRanges(shown);
      const pagesSet = new Set();
      merged.forEach(r=>{ for(let p=r.s;p<=r.e;p++) pagesSet.add(p); });

      return { blocks, merged, total: pagesSet.size };
    }

    function mergeRanges(ranges){
      if(ranges.length===0) return [];
      const sorted = [...ranges].sort((a,b)=>a.s-b.s);
      const out=[sorted[0]];
      for(let i=1;i<sorted.length;i++){
        const prev = out[out.length-1];
        const cur = sorted[i];
        if(cur.s <= prev.e+1){ // 相邻或重叠则合并
          prev.e = Math.max(prev.e, cur.e);
        }else{
          out.push({s:cur.s, e:cur.e});
        }
      }
      return out;
    }

    function fmtRange(s,e){ return `P${s}-P${e}`; }

    function render(result){
      list.innerHTML = '';
      result.blocks.forEach(b=>{
        const div=document.createElement('div');
        div.className='item';
        div.innerHTML = `<span class="badge">${b.label}</span><span class="range">${fmtRange(b.s,b.e)}</span>`;
        list.appendChild(div);
      });

      totalEl.textContent = result.total;
      mergedEl.textContent = result.merged.map(r=>fmtRange(r.s,r.e)).join('，');

      res.style.display = 'block';
    }

    function showError(msg){ err.innerHTML = msg || err.innerHTML; err.style.display='block'; res.style.display='none'; }
    function hideError(){ err.style.display='none'; }

    function handle(){
      const parsed = parseRange(input.value);
      if(!parsed){
        showError('❌ 输入不合法。请使用格式 <b>Px-Py</b>，且两页应为连续的 2 页（如 P12-P13）。');
        return;
      }
      hideError();
      const result = compute(parsed);
      render(result);
    }

    btn.addEventListener('click', handle);
    input.addEventListener('keydown', (e)=>{ if(e.key==='Enter') handle(); });

    // 示例：页面载入后给出一个占位示例
    window.addEventListener('DOMContentLoaded', ()=>{
      input.value='P29-P30';
    });
  </script>
</body>
</html>
